package com.ruoyi.system.service.impl;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.List;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.dto.ShipmentOrderDTO;
import com.ruoyi.system.dto.ShipmentOrderDetailDTO;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.vo.ShipmentOrderDetailVO;
import com.ruoyi.system.vo.ShipmentOrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.service.IShipmentOrderService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 出库单Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-12-12
 */
@Service
public class ShipmentOrderServiceImpl implements IShipmentOrderService
{
    @Autowired
    private ShipmentOrderMapper shipmentOrderMapper;

    @Autowired
    private ShipmentOrderDetailMapper shipmentOrderDetailMapper;

    @Autowired
    private WarehouseMapper wmsWarehouseMapper;

    @Autowired
    private WmsAreaMapper wmsAreaMapper;

    @Autowired
    private InventoryMapper inventoryMapper;

    @Autowired
    private CustomerTransactionMapper customerTransactionMapper;

    @Autowired
    private HistoryMapper inventoryHistoryMapper;

    /**
     * 查询出库单
     * 
     * @param id 出库单主键
     * @return 出库单
     */
    @Override
    public ShipmentOrderDTO selectShipmentOrderById(String id)
    {
        return shipmentOrderMapper.selectShipmentOrderById(id);
    }

    /**
     * 查询出库单列表
     * 
     * @param shipmentOrder 出库单
     * @return 出库单
     */
    @Override
    public List<ShipmentOrderDTO> selectShipmentOrderList(ShipmentOrderVO shipmentOrder)
    {
        return shipmentOrderMapper.selectShipmentOrderList(shipmentOrder);
    }

    /**
     * 新增出库单
     * 
     * @param shipmentOrder 出库单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertShipmentOrder(ShipmentOrderVO shipmentOrder) throws SQLException {
        long formId = Long.parseLong(shipmentOrder.getShipmentOrderNo().replace("-", "").substring(2));
        BigDecimal transactionAmount = new BigDecimal(0);
        //创建一个出库单的实例对象，并将所需要添加的值赋给新的实例对象进行增加
        ShipmentOrder sh = new ShipmentOrder();
        sh.setShipmentOrderNo(shipmentOrder.getShipmentOrderNo());
        sh.setShipmentOrderType(shipmentOrder.getShipmentOrderType());
        sh.setOrderNo(shipmentOrder.getOrderNo());
        sh.setCustomerId(shipmentOrder.getCustomerId());
        sh.setReceivableAmount(shipmentOrder.getReceivableAmount());
        sh.setRemark(shipmentOrder.getRemark());
        //循环查询仓库内是否有此物料
        boolean inventoryError = false;
        String errorMessage = "";

        if(shipmentOrder.getDetails().isEmpty()){
            throw new SQLException("请选择物料");
        }

        for (ShipmentOrderDetailVO item : shipmentOrder.getDetails()) {
            if(item.getWarehouseId() == null){
                inventoryError = true;
                errorMessage = "请选择仓库";
                break;
            }
            if(item.getAreaId() == null){
                inventoryError = true;
                errorMessage = "请选择库区";
                break;
            }

            transactionAmount = transactionAmount.add(item.getMoney());
            Warehouse wmsWarehouse = wmsWarehouseMapper.selectWarehouseById(item.getWarehouseId());
            WmsArea wmsArea = wmsAreaMapper.selectWmsAreaById(item.getAreaId());
            if(wmsArea == null){
                inventoryError = true;
                errorMessage = "请选择仓库所对应库区";
                break;
            }

            Inventory inventory = new Inventory();
            inventory.setItemId(item.getItemId());
            inventory.setWarehouseId(item.getWarehouseId());
            inventory.setAreaId(item.getAreaId());
            Inventory inv = inventoryMapper.selectInventoryByItemId(inventory);
            if (inv == null) {
                inventoryError = true;
                errorMessage = wmsWarehouse.getWarehouseName() + "库内" + wmsArea.getAreaName() + "缺少" + item.getItemName() + "物料";
                break;
            } else {
                item.setShipmentOrderId(formId);
                item.setCreateTime(DateUtils.getNowDate());
                shipmentOrderDetailMapper.insertShipmentOrderDetail(item);
            }
        }

        if (inventoryError) {
            throw new SQLException(errorMessage);
        }
        //3、查询客户是否有流水记录，获取之前的金额
        CustomerTransaction customer = customerTransactionMapper.selectCustomerTransactionById(shipmentOrder.getCustomerId());
        if(customer == null){
            customer = new CustomerTransaction();
            customer.setTransactionAmount(transactionAmount);
            customer.setPreviousBalance(new BigDecimal(0));
            customer.setCurrentBalance(customer.getTransactionAmount().add(customer.getPreviousBalance()));
        }else{
            customer.setTransactionAmount(transactionAmount);
            customer.setPreviousBalance(customer.getCurrentBalance());
            customer.setCurrentBalance(customer.getTransactionAmount().add(customer.getPreviousBalance()));
        }
        customer.setTransactionCode(shipmentOrder.getShipmentOrderNo());
        customer.setCustomerId(""+shipmentOrder.getCustomerId());
        customer.setTransactionType("2");
        customer.setShipmentOrderId(formId);
        customer.setRemark(shipmentOrder.getRemark());
        customer.setCreateTime(DateUtils.getNowDate());
        customerTransactionMapper.insertCustomerTransaction(customer);
        sh.setCreateTime(DateUtils.getNowDate());
        return AjaxResult.success(shipmentOrderMapper.insertShipmentOrder(sh));
    }

    /**
     * 修改出库单
     * 
     * @param shipmentOrder 出库单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateShipmentOrder(ShipmentOrderVO shipmentOrder) throws SQLException {
        long formId = Long.parseLong(shipmentOrder.getShipmentOrderNo().replace("-", "").substring(2));
        //创建一个出库单的实例对象，并将所需要修改的值赋给新的实例对象进行增加
        ShipmentOrder sh = new ShipmentOrder();
        sh.setShipmentOrderNo(shipmentOrder.getShipmentOrderNo());
        sh.setReceivableAmount(shipmentOrder.getReceivableAmount());
        sh.setRemark(shipmentOrder.getRemark());

        boolean inventoryError = false;
        String errorMessage = "";

        if(shipmentOrder.getDetails().isEmpty()){
            return AjaxResult.error("请选择物料");
        }

        for (ShipmentOrderDetailVO item : shipmentOrder.getDetails()) {

            //状态为发货或作废的不进行修改操作
            if(item.getShipmentOrderStatus() == 3 || item.getShipmentOrderStatus() == 4){
                continue;
            }

            if(item.getWarehouseId() == null){
                inventoryError = true;
                errorMessage = "请选择仓库";
                break;
            }
            if(item.getAreaId() == null){
                inventoryError = true;
                errorMessage = "请选择库区";
                break;
            }

            //循环查询仓库内是否有此物料
            Warehouse wmsWarehouse = wmsWarehouseMapper.selectWarehouseById(item.getWarehouseId());
            WmsArea wmsArea = wmsAreaMapper.selectWmsAreaById(item.getAreaId());
            if(wmsArea == null){
                inventoryError = true;
                errorMessage = "请选择仓库所对应库区";
                break;
            }
            Inventory inventory = new Inventory();
            inventory.setItemId(item.getItemId());
            inventory.setWarehouseId(item.getWarehouseId());
            inventory.setAreaId(item.getAreaId());
            Inventory inv = inventoryMapper.selectInventoryByItemId(inventory);
            if (inv == null) {
                inventoryError = true;
                errorMessage = wmsWarehouse.getWarehouseName() + "库内" + wmsArea.getAreaName() + "缺少" + item.getItemName() + "物料";
                break;
            } else {
                item.setShipmentOrderId(formId);
                ShipmentOrderDetail shipmentOrderDetail = shipmentOrderDetailMapper.selectShipmentOrderDetailById(item);
                if(shipmentOrderDetail != null){
                    shipmentOrderDetail.setPlanQuantity(item.getPlanQuantity());
                    shipmentOrderDetail.setMoney(item.getMoney());
                    shipmentOrderDetail.setWarehouseId(item.getWarehouseId());
                    shipmentOrderDetail.setAreaId(item.getAreaId());
                    shipmentOrderDetail.setUpdateTime(DateUtils.getNowDate());
                    shipmentOrderDetailMapper.updateShipmentOrderDetail(shipmentOrderDetail);
                }else{
                    item.setCreateTime(DateUtils.getNowDate());
                    shipmentOrderDetailMapper.insertShipmentOrderDetail(item);
                }
            }
        }

        if (inventoryError) {
            throw new SQLException(errorMessage);
        }
        //3、查询客户是否有流水记录，获取之前的金额
        CustomerTransaction customer = customerTransactionMapper.CustomerTransactionById(shipmentOrder.getCustomerId());
        customer.setTransactionAmount(shipmentOrder.getReceivableAmount());
        customer.setPreviousBalance(customer.getPreviousBalance());
        customer.setCurrentBalance(customer.getTransactionAmount().add(customer.getPreviousBalance()));
        customer.setTransactionCode(shipmentOrder.getShipmentOrderNo());
        customer.setRemark(shipmentOrder.getRemark());
        customer.setUpdateTime(DateUtils.getNowDate());
        customerTransactionMapper.updateCustomerTransaction(customer);
        sh.setUpdateTime(DateUtils.getNowDate());
        return AjaxResult.success(shipmentOrderMapper.updateShipmentOrder(sh));
    }

    /**
     * 批量删除出库单
     * 
     * @param id 需要删除的出库单主键
     * @return 结果
     */
    @Override
    public int deleteShipmentOrderByIds(String id)
    {
        String sub = id.replace("-", "").substring(2);
        shipmentOrderDetailMapper.deleteShipmentOrderDetailById(Long.valueOf(sub));
        return shipmentOrderMapper.deleteShipmentOrderByIds(id);
    }

    /**
     * 删除出库单信息
     * 
     * @param id 出库单主键
     * @return 结果
     */
    @Override
    public int deleteShipmentOrderById(Long id)
    {
        return shipmentOrderMapper.deleteShipmentOrderById(id);
    }

    /**
     * 修改出库单状态
     *
     * @param shipmentOrder 出库单主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateShipmentOrderByShipmentOrderNo(ShipmentOrderVO shipmentOrder) throws SQLException {

        //循环查询仓库内是否有此物料
        boolean inventoryError = false;
        String errorMessage = "";

        for (ShipmentOrderDetailVO detail : shipmentOrder.getDetails()) {
            if(detail.getShipmentOrderStatus() != 1){
                continue;
            }
            detail.setShipmentOrderStatus(shipmentOrder.getShipmentOrderStatus());
            Inventory inventory = new Inventory();
            inventory.setItemId(detail.getItemId());
            inventory.setWarehouseId(detail.getWarehouseId());
            inventory.setAreaId(detail.getAreaId());
            Warehouse wmsWarehouse = wmsWarehouseMapper.selectWarehouseById(detail.getWarehouseId());
            WmsArea wmsArea = wmsAreaMapper.selectWmsAreaById(detail.getAreaId());
            Inventory inv = inventoryMapper.selectInventoryByItemId(inventory);

            if(inv.getQuantity().compareTo(detail.getPlanQuantity()) >= 0){

                //修改库存记录
                inv.setQuantity(inv.getQuantity().subtract(detail.getPlanQuantity()));
                inventoryMapper.updateInventory(inv);

                //修改入库详情中的状态
                detail.setShipmentOrderId(Long.parseLong(shipmentOrder.getShipmentOrderNo().replace("-", "").substring(2)));
                shipmentOrderDetailMapper.updateShipmentOrderDetailState(detail);

                //创建库存记录表信息并添加进数据库
                History inventoryHistory = new History();
                inventoryHistory.setFormId(Long.parseLong(shipmentOrder.getShipmentOrderNo().replace("-", "").substring(2)));
                inventoryHistory.setFormType(2L);
                inventoryHistory.setItemId(detail.getItemId());
                inventoryHistory.setQuantity(detail.getPlanQuantity().negate());
                inventoryHistory.setCreateTime(DateUtils.getNowDate());
                inventoryHistory.setWarehouseId(detail.getWarehouseId());
                inventoryHistory.setAreaId(detail.getAreaId());
                inventoryHistoryMapper.insertHistory(inventoryHistory);

                //实例化发货对象

            }else{
                inventoryError = true;
                errorMessage = wmsWarehouse.getWarehouseName()+"库内"+wmsArea.getAreaName()+"的"+detail.getItemName()+"物料库存不足";
                break;
            }
        }
        if(inventoryError){
            throw new SQLException(errorMessage);
        }
        return AjaxResult.success(shipmentOrderMapper.updateShipmentOrderByShipmentOrderNo(shipmentOrder));
    }
}
